require File.dirname(__FILE__)+"/../test_helper"
require "starruby"
require "starframe/scene"

class TestStarFrameScene < Test::Unit::TestCase
  class Game
    attr_accessor :screen, :fps, :ticks
    attr_accessor :wait_count, :update_state_count, :update_screen_count
    attr_accessor :window_closing
    
    def initialize
      @wait_count = @update_state_count = @update_screen_count = 0
      @window_closing = false
    end
    
    def wait
      @wait_count += 1
    end
    
    def update_state
      @update_state_count += 1
    end
    
    def update_screen
      @update_screen_count += 1
    end
    
    def window_closing?
      @window_closing
    end
  end
  
  class TestScene < StarFrame::Scene
    attr_reader :update_count, :render_count, :running
    attr_reader :screen
    
    def init *args
      @running = true
      @update_count = 0
      @render_count   = 0
    end
    
    def quit
      @running = false
    end
    
    def update
      @update_count += 1
    end
    
    def render
      @render_count += 1
    end
  end
  
  def setup
    @game = Game.new
    @game.screen = StarRuby::Texture.new(640, 480)
    @scene = TestScene.new(@game)
  end
  
  def test_default
    assert_equal 0, @scene.update_count
    assert_equal 0, @scene.render_count
    assert_equal true, @scene.running
    assert_equal @game.screen, @scene.screen
  end
  
  def test_call
    (0...60).each do |ticks|
      @game.screen.last_method = nil
      @scene.call
      assert_equal 1+ticks, @scene.update_count
      assert_equal 1+ticks, @scene.render_count
      assert_equal :clear, @scene.screen.last_method
      
      assert_equal 0, @game.wait_count
      assert_equal 0, @game.update_state_count
      assert_equal 0, @game.update_screen_count
    end
  end
  
  def test_exit_scene
    def @scene.update
      @update_count += 1
      exit_scene
      @update_count += 1
    end
    
    @scene.call
    assert_equal 1, @scene.update_count
    assert_equal 0, @scene.render_count
    assert_equal false, @scene.running
  end
  
  def test_start_and_exit_scene
    def @scene.update
      @update_count += 1
      exit_scene if @update_count == 60
    end
    
    assert_equal nil, @scene.start
    assert_equal 60, @scene.update_count
    assert_equal 59, @scene.render_count
    assert_equal false, @scene.running
    
    assert_equal 60, @game.wait_count
    assert_equal 60, @game.update_state_count
    assert_equal 59, @game.update_screen_count
  end
  
  def test_start_and_next_scene
    def @scene.update
      @update_count += 1
      next_scene :next_scene if @update_count == 60
    end
    
    assert_equal :next_scene, @scene.start
    assert_equal 60, @scene.update_count
    assert_equal 59, @scene.render_count
    assert_equal false, @scene.running
    
    assert_equal 60, @game.wait_count
    assert_equal 60, @game.update_state_count
    assert_equal 59, @game.update_screen_count
  end
  
  def test_start_and_window_closing
    def @scene.update
      @update_count += 1
      @game.window_closing = true if @update_count == 60
    end
    
    assert_equal nil, @scene.start
    assert_equal 60, @scene.update_count
    assert_equal 60, @scene.render_count
    assert_equal false, @scene.running
    
    assert_equal 60, @game.wait_count
    assert_equal 60, @game.update_state_count
    assert_equal 60, @game.update_screen_count
  end
end
